package com.cblz.bd.server.core.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cblz.bd.common.core.constant.RedisConstant;
import com.cblz.bd.common.core.entity.BaConfig;
import com.cblz.bd.common.core.exception.BdAdminException;
import com.cblz.bd.common.core.utils.BdAdminUtil;
import com.cblz.bd.redis.spring.boot.starter.service.RedisService;
import com.cblz.bd.server.core.mapper.BaConfigMapper;
import com.cblz.bd.server.core.service.BaConfigService;
import io.vavr.Tuple3;
import io.vavr.control.Option;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yanjieping
 * @description 针对表【ba_config(系统配置)】的数据库操作Service实现
 * @createDate 2022-11-04 15:09:53
 */
@Slf4j
@Service("baConfigService")
@RequiredArgsConstructor
public class BaConfigServiceImpl extends ServiceImpl<BaConfigMapper, BaConfig> implements BaConfigService {

    private final RedisService redisService;

    @Override
    public Map<String, Object> getAllInfoByPage(Tuple3<Page<BaConfig>, QueryWrapper<BaConfig>, Object> wrapperBaConfigTuple3) {
        Page<BaConfig> baConfigPage = wrapperBaConfigTuple3._1;
        QueryWrapper<BaConfig> baConfigQueryWrapper = wrapperBaConfigTuple3._2;

        return BdAdminUtil.pageResult(baseMapper.selectPage(baConfigPage, baConfigQueryWrapper));
    }

    /**
     * 拿取所有信息返回给后台管理端
     *
     * @return
     */
    @Override
    public Map<String, Object> getAllInfoByAdmin() {
        List<BaConfig> baConfigList = Option.of(this.list()).getOrElseThrow(() -> {
            throw new BdAdminException("系统配置信息为空");
        });

        Map<String, Object> configGroupMap = new HashMap<>();
        JSONArray quickEntranceMap = new JSONArray();

        Iterator<BaConfig> iterator = baConfigList.iterator();
        while (iterator.hasNext()) {
            BaConfig next = iterator.next();
            if (StringUtils.equals(next.getName(), "config_group")) {
                for (Object json : JSONUtil.parseArray(next.getValue())) {
                    JSONObject entries = JSONUtil.parseObj(json);
                    configGroupMap.put(entries.get("key").toString(), entries.get("value"));
                }
            }
            if (StringUtils.equals(next.getName(), "config_quick_entrance")) {
                quickEntranceMap = JSONUtil.parseArray(next.getValue());
            }
        }

        Map<String, List<BaConfig>> collect = baConfigList.stream().collect(Collectors.groupingBy(BaConfig::getGroup));
        Map<String, Map<String, Object>> listMap = new HashMap();
        Map<String, Object> finalConfigGroupMap = configGroupMap;
        collect.forEach((key, value) -> {
            Map<String, Object> mapHandle = new HashMap<>();
            String title = finalConfigGroupMap.get(key).toString();
            mapHandle.put("list", value.stream().peek(baConfig -> {
                if (StringUtils.equals("array", baConfig.getType()))
                    baConfig.setValue(JSONUtil.parseArray(baConfig.getValue()));
            }).sorted(Comparator.comparingInt(BaConfig::getWeigh).reversed()).collect(Collectors.toList()));
            mapHandle.put("name", key);
            mapHandle.put("title", title);
            listMap.put(key, mapHandle);
        });

        return Map.of("list", listMap, "remark", "", "configGroup", configGroupMap, "quickEntrance", quickEntranceMap);
    }

    /**
     * 修改配置信息
     *
     * @param params 参数列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editConfigInfo(Map<String, Object> params) {
        Assert.notNull(params);
        List<BaConfig> updateBatchList = new ArrayList<>(Collections.EMPTY_LIST);

        params.forEach((key, val) -> {
            if (StringUtils.equals("null", RedisConstant.SYSTEM_CONFIG_CACHE_PREFIX.getValue() + key + "--null"))
                throw new BdAdminException("找不到对应系统配置信息:" + key);

            BaConfig baConfig = (BaConfig) redisService.get(RedisConstant.SYSTEM_CONFIG_CACHE_PREFIX.getValue() + key);
            if (Objects.isNull(baConfig)) {
                baConfig = getOne(new LambdaQueryWrapper<BaConfig>().eq(BaConfig::getName, key));
                if (Objects.isNull(baConfig)) {
                    redisService.set(RedisConstant.SYSTEM_CONFIG_CACHE_PREFIX.getValue() + key + "--null", "null", 60 * 2L);
                    throw new BdAdminException("找不到对应系统配置信息:" + key);
                }
                redisService.set(RedisConstant.SYSTEM_CONFIG_CACHE_PREFIX.getValue() + key, baConfig, 60 * 10L);
            }

            if (StringUtils.equals(baConfig.getType(), "array")) {
                val = JSONUtil.toJsonStr(val);
            }
            baConfig.setValue(val);
            updateBatchList.add(baConfig);
        });

        updateBatchById(updateBatchList);
    }

    /**
     * 系统进入时获取的配置
     *
     * @return
     */
    @Override
    public Map<String, Object> getInitConfig() {
        return Option.of(list(new LambdaQueryWrapper<BaConfig>().in(BaConfig::getName, "site_name", "record_number", "version"))).getOrElseThrow(() -> {
            throw new BdAdminException("获取系统首页进入时的配置失败，配置为空!");
        }).stream().collect(Collectors.toMap(BaConfig::getName, BaConfig::getValue));
    }
}




